home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / system / startppp.000 / startppp / Startppp_v0.80 / Modem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-15  |  17.1 KB  |  757 lines

  1. /*
  2.  * Startppp
  3.  *
  4.  * Copyright (C) 1995  Matthias Ott 
  5.  *  (msott@cip.informatik.uni-erlangen.de)
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this program; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "tk.h"
  25. #include <time.h>
  26. #include <unistd.h>
  27. #include <signal.h>
  28. #include <stdlib.h>
  29. #include <fcntl.h>
  30. #include <termios.h>
  31. #include <sys/types.h>
  32. #include <sys/time.h>
  33. #include <sys/wait.h>
  34. #include "Modem.h"
  35.  
  36.  
  37. char dialerror[]="dialerror\n";
  38. char dialkill[]="dialkill\n";
  39. char dialup[]="dialup\n";
  40. char dialconnect[]="dialconnect\n";
  41. char dialend[]="dialend\n";
  42. int fd=-1;
  43. int childpid=0;
  44. int pipefd[2];
  45. int pipeterminalfd[2];
  46. int timeout;
  47. int timeouttime;
  48. int showtermint=0;
  49. Tcl_Interp *myinterp;
  50.  
  51. /*
  52.    **    Function name : alarm_handler
  53.    **
  54.    **    Description :
  55.    **    Input :
  56.    **    Output :
  57. */
  58. void alarm_handler(int x)
  59. {
  60.   char dialtimeout[]="timeout -> closed line";
  61.   write (pipefd[1], dialtimeout, strlen(dialtimeout));
  62.   timeout=1;
  63. }
  64.  
  65.  
  66. /*
  67.    **    Function name : modemdial
  68.    **
  69.    **    Description :
  70.    **    Input : init number
  71.    **    Output :
  72. */
  73. int modemdial(char *modeminit, char *modemconnect)
  74. {
  75.   int len,i,ii;
  76.   int number=0;
  77.   char buf[60];
  78.   char buf2[20];
  79.   char action[200];
  80.   int again = 1;
  81.   struct sigaction sigalarm={
  82.     alarm_handler,0,0};
  83.  
  84.   timeout=0;
  85.   
  86.   if (sigaction(SIGALRM, &sigalarm,NULL)!=0) {
  87.     perror("SIGALRM: ");
  88.   }
  89.     
  90.   i=0;
  91.   ii=0;
  92.   while (i < strlen (modeminit)) {
  93.     if (modeminit[i]=='~') {
  94.       sleep(1);
  95.       ++i;
  96.       continue;
  97.     }
  98.     ii=0;
  99.     while ((modeminit[i]!='^') && (modeminit[i+1]!='M') && (i < strlen (modeminit))) {
  100.       action[ii]=modeminit[i];
  101.       ++i;
  102.       ++ii;
  103.     }
  104.     i=i+2;
  105.     action[ii]='\0';
  106.     write (pipefd[1], action, strlen(action));
  107.     strncat(action,"\r",1); 
  108.     write (fd, action, strlen(action));
  109.   }
  110.   
  111.   /* magic sleep, should change it */
  112.   sleep(2);
  113.   write (pipefd[1], modemconnect, strlen(modemconnect));
  114.   write (fd, modemconnect, strlen(modemconnect));
  115.   modemwait(modemconnect);
  116.  
  117.   buf[0]='\0';
  118.   alarm(timeouttime);
  119.   do {
  120.     number=0;
  121.     do {
  122.       number=read (fd, buf2,20);
  123.     } while ((number == 0) && (again == 1) &&(timeout == 0));
  124.     if ((number == -1) && (timeout == 0)) {
  125.       alarm(0);
  126.       printf("read error at modemdial\n");
  127.       return 7;
  128.     }
  129.     if (timeout == 1) {
  130.       sleep (1);
  131.       write (pipefd[1], dialerror, strlen(dialerror));
  132.       while(1) sleep (1000);
  133.     }
  134.     buf2[number]='\0';
  135.     if (showtermint == 1) {
  136.       write (pipeterminalfd[1], buf2, number);
  137.     }
  138.     strcat (buf,buf2);
  139.     
  140.     if (strstr(buf,"BUSY")!=NULL) {
  141.       alarm(0);
  142.       return 6;
  143.     }
  144.     if (strstr(buf,"NO ANSWER")!=NULL) {
  145.       alarm(0);
  146.       write (pipefd[1], "NO ANSWER", 9);
  147.       sleep (1);
  148.       return 7;
  149.     }
  150.     if (strstr(buf,"DELAYED")!=NULL) {
  151.       alarm(0);
  152.       write (pipefd[1], "DELAYED", 7);
  153.       sleep (1);
  154.       return 7;
  155.     }
  156.     if (strstr(buf,"NO DIALTONE")!=NULL) {
  157.       alarm(0);
  158.       write (pipefd[1], "NO DIALTONE", 11);
  159.       sleep (1);
  160.       return 7;
  161.     }
  162.     if (strstr(buf,"ERROR")!=NULL) {
  163.       alarm(0);
  164.       write (pipefd[1], "ERROR", 5);
  165.       sleep (1);
  166.       return 7;
  167.     }
  168.     if (strstr(buf,"NO CARRIER")!=NULL) {
  169.       alarm(0);
  170.       write (pipefd[1], "NO CARRIER", 10);
  171.       sleep (1);
  172.       return 7;
  173.     }
  174.     if (strstr(buf,"CARRIER")!=NULL) {
  175.       alarm(0);
  176.       return 0;
  177.     }
  178.     if (strstr(buf,"CONNECT")!=NULL) {
  179.       alarm(0);
  180.       return 0;
  181.     }
  182.     if (again >= 10) {
  183.       alarm(0);
  184.       write (pipefd[1], "ANY ERROR", 9);
  185.       sleep (1);
  186.       return 7;
  187.     }
  188.     ++again;
  189.     
  190.   } while (1);
  191. }
  192.  
  193. /*
  194.    **    Function name : ModemClose
  195.    **
  196.    **    Description :
  197.    **    Input : modemdevicetail
  198.    **    Output : UNLINK DENIED | CLOSED
  199. */
  200. int ModemClose(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
  201. {
  202.   char buf[256];
  203.   struct termios t;
  204.   char *modemdevice;
  205.   char *modemdevicetail;
  206.   char *modemspeed;
  207.   char *modemparity;
  208.   char *modemstopbits;
  209.   int result;
  210.   
  211.   if (argc != 2) {
  212.     interp->result = "wrong # args";
  213.     return TCL_ERROR;
  214.   }
  215.   if (fd==-1) {
  216.     modemdevice=Tcl_GetVar(interp, "modemdevice", TCL_GLOBAL_ONLY);
  217.     strcpy(modemdevicetail,argv[1]);
  218.     modemspeed=Tcl_GetVar(interp, "modemspeed", TCL_GLOBAL_ONLY);
  219.     modemparity=Tcl_GetVar(interp, "modemparity", TCL_GLOBAL_ONLY);
  220.     modemstopbits=Tcl_GetVar(interp, "modemstopbits", TCL_GLOBAL_ONLY);
  221.     result=modemopen(modemdevice,modemdevicetail,modemspeed,modemparity,modemstopbits);
  222.     if (result==1) {
  223.       interp->result = "can't open LCK.. for reading";
  224.       return TCL_OK;
  225.     }
  226.     if (result==2) {
  227.       interp->result = "LCK process active";
  228.       return TCL_OK;
  229.     }
  230.     if (result==3) {
  231.       interp->result = "can't delete LCK..";
  232.       return TCL_OK;
  233.     }
  234.     if (result==4) {
  235.       interp->result = "can't open LCK.. for writing";
  236.       return TCL_OK;
  237.     }
  238.     if (result==5) {
  239.       interp->result = "can't open modemdevice";
  240.       return TCL_OK;
  241.     }
  242.     if (result==6) {
  243.       interp->result = "tcget|setattr error";
  244.       return TCL_OK;
  245.     }
  246.   }
  247.  
  248.   if (tcgetattr(fd,&t) < 0) {
  249.     Tcl_SetVar(myinterp, "message", "tcsetattr is not working", TCL_GLOBAL_ONLY);
  250.   } else {
  251.     t.c_cflag=B0;
  252.     if (tcsetattr(fd,TCSANOW,&t) < 0) {
  253.       Tcl_SetVar(myinterp, "message", "tcgetattr is not working", TCL_GLOBAL_ONLY);
  254.     }
  255.   }
  256.  
  257.   close (fd);
  258.   fd = -1;
  259.   sprintf(buf,"/usr/spool/uucp/LCK..%s",argv[1]);
  260.   if (unlink (buf) != 0) {
  261.     interp->result = "unlink denied";
  262.     return TCL_OK;
  263.   }
  264.   interp->result = "closed line";
  265.   return TCL_OK;
  266. }
  267. /*
  268.    **    Function name : modemtalk
  269.    **
  270.    **    Description :
  271.    **    Input : file
  272.    **    Output : 1 | 0 
  273. */
  274. int modemtalk(char *expectfile)
  275. {
  276.   char name[100];
  277.   int len;
  278.   FILE *fd2;
  279.   char dialfile[]="no expectfile";
  280.   
  281.   fd2=fopen(expectfile,"r");
  282.   if (fd2==NULL) {
  283.     write (pipefd[1], dialfile, strlen(dialfile));
  284.     return 1;
  285.   }
  286.   while (fgets(name,100,fd2)!=NULL) {
  287.     len = strlen(name);
  288.     name[len-1]='\0';
  289.     modemwait (name);
  290.     fgets(name,100,fd2);
  291.     write (fd, name, strlen(name));
  292.   }
  293.   fclose (fd2);
  294.   
  295.   return 0;
  296. }
  297.  
  298. /*
  299.    **    Function name : modemwait
  300.    **
  301.    **    Description :
  302.    **    Input :
  303.    **    Output :
  304. */
  305. int modemwait(char *name)
  306. {
  307.   int r;
  308.   int i;
  309.   int number=0;
  310.   char buf[5000];
  311.   char myname[100];
  312.   struct sigaction sigalarm={
  313.     alarm_handler,0,0};
  314.   strcpy(myname,name);
  315.   r=0;
  316.   
  317.   timeout=0;
  318.   if (sigaction(SIGALRM, &sigalarm,NULL)!=0) {
  319.     perror("SIGALRM: ");
  320.   }
  321.   alarm(timeouttime);
  322.   do {
  323.     number=0;
  324.     while ((number == 0) && (timeout == 0)) {
  325.       number=read (fd, &buf[r],1);
  326.     }
  327.                  
  328. /*
  329.    if ((number == -1) && (timeout == 0)) {
  330.    alarm(0);
  331.    printf("read error at modemwait\n");
  332.    write (pipefd[1], dialerror, strlen(dialerror));
  333.    while(1) sleep (1000);
  334.    }
  335. */
  336.     if (timeout == 1) {
  337.       write (pipefd[1], dialerror, strlen(dialerror));
  338.       while(1) sleep (1000);
  339.     }
  340.     buf[r+1]='\0';
  341.     
  342.     if (showtermint == 1) {
  343.       write (pipeterminalfd[1], &buf[r], 1);
  344.     }
  345.     if (buf[r]=='\0') {
  346.       buf[r]==' ';
  347.     }
  348.     r++;
  349.     if (r >= 5000) {
  350.       r = 0;
  351.     }
  352.   } while ((strstr(buf, myname)==NULL) && (timeout == 0));
  353.   alarm(0);
  354.   return 0;
  355. }
  356.  
  357. /*
  358.    **    Function name : modemopen
  359.    **
  360.    **    Description :
  361.    **    Input : device lock
  362.    **    Output : 
  363. */
  364. int modemopen(char *modemdevice, char *modemdevicetail, char *modemspeed, char *modemparity, char *modemstopbits)
  365. {
  366.   FILE *fp;
  367.   char buf[256];
  368.   int pid=0;
  369.   struct termios t;
  370.   
  371.   sprintf(buf,"/usr/spool/uucp/LCK..%s",modemdevicetail);
  372.   fp = fopen(buf, "r");
  373.   if (fp == NULL) {
  374.     if (errno != ENOENT) {
  375.       return 1;
  376.     }
  377.   } 
  378.   else {
  379.     fscanf(fp, "%d", &pid);
  380.     fclose (fp);
  381.     if (getpid()!=pid) {
  382.       if (kill(pid,0)==0) {
  383.     return 2;
  384.       }
  385.     }
  386.     else {
  387.       if (unlink (buf) != 0) {
  388.     return 3;
  389.       }
  390.     }
  391.   }
  392.   fp = fopen(buf,"w");
  393.   if (fp == NULL) {
  394.     return 4;
  395.   }
  396.   fprintf(fp,"%d\n",getpid());
  397.   fclose(fp);
  398.   
  399.   fd = open(modemdevice, O_RDWR | O_NDELAY);
  400.   if (fd<0) {
  401.     printf("MODEM open error\n");
  402.     return 5;
  403.   }
  404.   fcntl(fd,F_SETFL,O_RDWR);
  405.   if (tcgetattr(fd,&t)<0) {
  406.     perror("tcgetattr not working");
  407.     close(fd);
  408.     fd = -1;
  409.     return 6;
  410.   }
  411.   t.c_iflag=t.c_oflag=t.c_lflag=0;
  412.   t.c_cc[VMIN]=1;
  413.   t.c_cc[VTIME]=0;
  414.   
  415.   /* Setzen der Flags */
  416.   if (strcmp(modemparity, "CS8")==0) t.c_cflag = CREAD | CS8;
  417.   if (strcmp(modemparity, "CS8|PARENB ")==0) t.c_cflag = CREAD | CS8 | PARENB;
  418.   if (strcmp(modemparity, "CS8|PARENB|PARODD")==0) t.c_cflag = CREAD | CS8 | PARENB | PARODD;
  419.   
  420.   if (strcmp(modemspeed, "38400")==0) t.c_cflag |= B38400;
  421.   if (strcmp(modemspeed, "19200")==0) t.c_cflag |= B19200;
  422.   if (strcmp(modemspeed, "9600")==0) t.c_cflag |= B9600;
  423.   if (strcmp(modemspeed, "1200")==0) t.c_cflag |= B1200;
  424.   
  425.   if (strcmp(modemstopbits, "CSTOPB")==0) t.c_cflag |= CSTOPB;
  426.   t.c_cflag |= HUPCL;
  427.   /*  t.c_cflag=CREAD | CS8 | B38400 | HUPCL;*/
  428.   if (tcsetattr(fd,TCSANOW,&t)<0) {
  429.     perror("tcsetattr not working");
  430.     close(fd);
  431.     fd = -1;
  432.     return 6;
  433.   }
  434.   return 0;
  435.   
  436. }
  437.  
  438.  
  439.  
  440. /*
  441.    **    Function name : TalkTerminal
  442.    **
  443.    **    Description :
  444.    **    Input :
  445.    **    Output :
  446. */
  447. void TalkTerminal(ClientData clientData, int mask)
  448. {
  449.   int count,i;
  450.   char input[1000];
  451.   char order[1000];
  452.   char order2[]=".sm.input.text yview -pickplace end\n";
  453.  
  454.   count=read(pipeterminalfd[0], input, 1000);
  455.   if (count <=0) {
  456.     printf("ERROR reading PIPE");
  457.     return;
  458.   }
  459.   input[count]='\0';
  460.   for (i=0;i<count;++i) {
  461.     if (input[i]=='\r') {
  462.       input[i]=' ';
  463.     }
  464.   }
  465.   sprintf(order,".sm.input.text insert end {%s}",input);
  466.   Tcl_Eval (myinterp, order);
  467.   Tcl_Eval (myinterp, order2);
  468. }
  469.  
  470. /*
  471.    **    Function name : TalkProc
  472.    **
  473.    **    Description :
  474.    **    Input :
  475.    **    Output :
  476. */
  477. void TalkProc(ClientData clientData, int mask)
  478. {
  479.   int i;
  480.   int count;
  481.   char *buf; 
  482.   int bufint;
  483.   char up2[]="up2";
  484.   char startonlinetime[]="startonlinetime";
  485.   char input[100];
  486.   char order [100];
  487.   char *modemdevicetail;
  488.   char *startcommand;
  489.   
  490.   count=read(pipefd[0], input, 100);
  491.  
  492.   if (count <=0) {
  493.     printf("ERROR reading PIPE");
  494.     return;
  495.   }
  496.   input[count]='\0';
  497.   
  498.   /* increase dialtry +1 */
  499.   if (strstr(input, dialup)!=NULL) {
  500.     buf=Tcl_GetVar(myinterp, "dialtry", TCL_GLOBAL_ONLY);
  501.     Tcl_GetInt(myinterp, buf, &bufint);
  502.     ++bufint;
  503.     sprintf(buf,"%d",bufint); 
  504.     Tcl_SetVar(myinterp, "dialtry", buf, TCL_GLOBAL_ONLY);
  505.     return;
  506.   }
  507.   
  508.   /* error while dialing, close modemline */
  509.   if (strstr(input, dialerror)!=NULL) {
  510.     Tcl_SetVar(myinterp, "dialtry", "0", TCL_GLOBAL_ONLY);
  511.     modemdevicetail=Tcl_GetVar(myinterp, "modemdevicetail", TCL_GLOBAL_ONLY);
  512.     sprintf(order,"modemclose %s",modemdevicetail);
  513.     Tcl_Eval (myinterp, order);
  514.     pidkill();
  515.     return;
  516.   }
  517.   
  518.   /* error, only kill childprocess */
  519.   if (strstr(input, dialkill)!=NULL) {
  520.     Tcl_SetVar(myinterp, "dialtry", "0", TCL_GLOBAL_ONLY);
  521.     pidkill();
  522.     return;
  523.   }
  524.   
  525.   /* got a connect, set LINE up, start onlinetime */
  526.   if (strstr(input, dialconnect)!=NULL) {
  527.     Tcl_SetVar(myinterp, "message", "connected", TCL_GLOBAL_ONLY);
  528.     Tcl_SetVar(myinterp, "dialtry", "0", TCL_GLOBAL_ONLY);
  529.     Tcl_SetVar(myinterp, "linestatus", "LINE up", TCL_GLOBAL_ONLY);
  530.     Tcl_Eval (myinterp, startonlinetime);
  531.     return;
  532.   }
  533.   
  534.   /* sucessfull dialing, start <up2> */
  535.   if (strstr(input, dialend)!=NULL) {
  536.     Tcl_Eval (myinterp, up2);
  537.     Tcl_SetVar(myinterp, "pid", "0", TCL_GLOBAL_ONLY);
  538.     pidkill();
  539.     return;
  540.   }
  541.   
  542.   Tcl_SetVar(myinterp, "message", input, TCL_GLOBAL_ONLY);
  543.   return;
  544. }
  545.  
  546.  
  547.  
  548. /*
  549.    **    Function name : DialProc
  550.    **
  551.    **    Description :
  552.    **    Input :
  553.    **    Output :
  554. */
  555. int DialProc(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
  556. {
  557.   int pid;
  558.   char *modemdevice;
  559.   char *modemdevicetail;
  560.   char *modemspeed;
  561.   char *modemparity;
  562.   char *modemstopbits;
  563.   char *modemtimeout;
  564.   char *showterminal;
  565.   int result;
  566.   if (childpid != 0) {
  567.     interp->result="line already active";
  568.     return TCL_OK;
  569.   }
  570.   
  571.   modemdevice=Tcl_GetVar(interp, "modemdevice", TCL_GLOBAL_ONLY);
  572.   modemdevicetail=Tcl_GetVar(interp, "modemdevicetail", TCL_GLOBAL_ONLY);
  573.   modemspeed=Tcl_GetVar(interp, "modemspeed", TCL_GLOBAL_ONLY);
  574.   modemparity=Tcl_GetVar(interp, "modemparity", TCL_GLOBAL_ONLY);
  575.   modemstopbits=Tcl_GetVar(interp, "modemstopbits", TCL_GLOBAL_ONLY);
  576.   modemtimeout=Tcl_GetVar(interp, "modemtimeout", TCL_GLOBAL_ONLY);
  577.   showterminal=Tcl_GetVar(interp, "showterminal", TCL_GLOBAL_ONLY);
  578.   Tcl_GetInt(interp, showterminal, &showtermint);
  579.   Tcl_GetInt(interp, modemtimeout, &timeouttime);
  580.  
  581.   /* open the modemdevice */
  582.   result=modemopen(modemdevice,modemdevicetail,modemspeed,modemparity,modemstopbits);
  583.   if (result==1) {
  584.     interp->result = "can't open LCK.. for reading";
  585.     return TCL_OK;
  586.   }
  587.   if (result==2) {
  588.     interp->result = "LCK process active";
  589.     return TCL_OK;
  590.   }
  591.   if (result==3) {
  592.     interp->result = "can't delete LCK..";
  593.     return TCL_OK;
  594.   }
  595.   if (result==4) {
  596.     interp->result = "can't open LCK.. for writing";
  597.     return TCL_OK;
  598.   }
  599.   if (result==5) {
  600.     interp->result = "can't open modemdevice";
  601.     return TCL_OK;
  602.   }
  603.   if (result==6) {
  604.     interp->result = "tcget|setattr error";
  605.     return TCL_OK;
  606.   }
  607.   
  608.   /* Pipes are initiated */
  609.   if (pipe(pipefd) == -1) {
  610.     interp->result="pipe error";
  611.     return TCL_OK;
  612.   }
  613.   if (showtermint == 1) {
  614.     if (pipe(pipeterminalfd) == -1) {
  615.       interp->result="pipe error";
  616.       return TCL_OK;
  617.     }
  618.   }
  619.   
  620.   /* forking */
  621.   if ((pid = fork()) > 0) {  /* parent process  */
  622.     myinterp=interp;
  623.     Tk_CreateFileHandler(pipefd[0],TK_READABLE,TalkProc,(ClientData) NULL); 
  624.  
  625.     /* show terminal */
  626.     if (showtermint == 1) {
  627.       Tk_CreateFileHandler(pipeterminalfd[0],TK_READABLE,TalkTerminal,(ClientData) NULL); 
  628.     }
  629.     
  630.     /* set childpid on pid */
  631.     childpid=pid;
  632.     sprintf(interp->result,"%d",childpid);
  633.     return TCL_OK;
  634.   }
  635.   else {
  636.     if (pid == 0) {  /* child process */
  637.       
  638.       char *dialtype;
  639.       char *modemnumber;
  640.       char *modeminit;
  641.       char modemconnect[30];
  642.       char *expectfile;
  643.       char *dialtry;
  644.       char *repeatdelay;
  645.       char dialbusy[]="line is busy";
  646.       char dialerror2[]="error while dialing";
  647.       int delay;
  648.       int dialint;
  649.       
  650.       repeatdelay=Tcl_GetVar(interp, "repeatdelay", TCL_GLOBAL_ONLY);
  651.       Tcl_GetInt(interp, repeatdelay, &delay);
  652.       dialtype=Tcl_GetVar(interp, "dialtype", TCL_GLOBAL_ONLY);
  653.       modemnumber=Tcl_GetVar(interp, "modemnumber", TCL_GLOBAL_ONLY);
  654.       modeminit=Tcl_GetVar(interp, "modeminit", TCL_GLOBAL_ONLY);
  655.       expectfile=Tcl_GetVar(interp, "expectfile", TCL_GLOBAL_ONLY);
  656.  
  657.       sprintf(modemconnect,"ATD%s%s\r",dialtype,modemnumber);
  658.       
  659.       while (1) {
  660.     dialtry=Tcl_GetVar(interp, "dialtry", TCL_GLOBAL_ONLY);
  661.     Tcl_GetInt(interp, dialtry, &dialint);
  662.     ++dialint;
  663.     sprintf(dialtry,"%d",dialint);
  664.     write (pipefd[1], dialup, strlen(dialup));
  665.     
  666.     result=modemdial(modeminit, modemconnect);
  667.     if (result == 0) {
  668.       write (pipefd[1], dialconnect, strlen(dialconnect));
  669.       if (modemtalk(expectfile)!=0) {
  670.         write (pipefd[1], dialerror, strlen(dialerror));
  671.         while(1) sleep (1000);
  672.       }
  673.     }
  674.     if (result == 6) { /* BUSY */
  675.       write (pipefd[1], dialbusy, strlen(dialbusy));
  676.       sleep(delay);
  677.       continue;
  678.     }  
  679.     if (result == 7) { /* ERROR */
  680.       write (pipefd[1], dialerror, strlen(dialerror));
  681.       while(1) sleep (1000);
  682.     }
  683.     break;
  684.       }
  685.       write (pipefd[1], dialend, strlen(dialend));
  686.       while(1) sleep (1000);
  687.     }
  688.     else { /* <fork> error */
  689.       interp->result = "fork error";
  690.       return TCL_OK;
  691.     }
  692.   }
  693. }
  694.  
  695. /*
  696.    **    Function name : KillPid
  697.    **
  698.    **    Description :
  699.    **    Input :
  700.    **    Output :
  701. */
  702. int KillPid(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
  703. {
  704.   if (argc != 1) {
  705.     interp->result = "wrong # args";
  706.     return TCL_ERROR;
  707.   }
  708.   
  709.   if (childpid==0) {
  710.     interp->result = "child not active";
  711.     return TCL_OK;
  712.   }
  713.   /* close the handler */
  714.   Tk_DeleteFileHandler(pipefd[0]);
  715.   close (pipefd[0]);
  716.   close (pipefd[1]);
  717.   if (showtermint == 1) {
  718.     Tk_DeleteFileHandler(pipeterminalfd[0]);
  719.     close (pipeterminalfd[0]);
  720.     close (pipeterminalfd[1]);
  721.   }
  722.  
  723.   /* kill child */
  724.   if (kill (childpid, 2)==0) {
  725.     waitpid (childpid,NULL,0);
  726.     childpid=0;
  727.     interp->result = "killed child process";
  728.     return TCL_OK;
  729.   }
  730.   interp->result = "failed to kill child";
  731.   return TCL_OK;
  732. }
  733.  
  734. /*
  735.    **    Function name : pidkill
  736.    **
  737.    **    Description :
  738.    **    Input :
  739.    **    Output :
  740. */
  741. void pidkill(void)
  742. {
  743.   Tk_DeleteFileHandler(pipefd[0]);
  744.   close (pipefd[0]);
  745.   close (pipefd[1]);
  746.   if (showtermint == 1) {
  747.     Tk_DeleteFileHandler(pipeterminalfd[0]);
  748.     close (pipeterminalfd[0]);
  749.     close (pipeterminalfd[1]);
  750.   }
  751.   if(kill(childpid, 2)==0) {
  752.     waitpid(childpid,NULL,0);
  753.     childpid=0;
  754.   }
  755. }
  756.  
  757.